﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using Microsoft.Win32;
using System.Windows;
using System.Xml;
using WinForm = System.Windows.Forms;
using SHomeWorkshop.LunarConcept.Controls;
using SHomeWorkshop.LunarConcept.Tools;
using SHomeWorkshop.LunarConcept.ModifingManager;
using System.Windows.Media;

namespace SHomeWorkshop.LunarConcept.Commands
{
    /// <summary>
    /// 创建时间：2012年8月5日
    /// 创建者：  杨震宇
    /// 
    /// 主要用途：创建字贴命令。
    /// ★★说明：关于自定义命令的实现，可参考“NewDocument”类的备注。
    /// </summary>
    public static class CreateCopybookCommand
    {
        #region 构造方法=====================================================================================================

        /// <summary>
        /// ★②，修改静态构造方法名。
        /// </summary>
        static CreateCopybookCommand()//类型构造器
        {
            //★③，修改两个字符串参数名。★④以及第三个参数的类型名。
            routedUICmd = new RoutedUICommand(
                "CreateCopybookCommand",
                "CreateCopybookCommand",
                typeof(CreateCopybookCommand),//创建RoutedUICommand对象
                null);

            //如果需要挂接快捷键，请参考下面这段代码：
            //routedUICmd = new RoutedUICommand(
            //    "SaveDocumentCommand",
            //    "SaveDocumentCommand",
            //    typeof(SaveDocumentCommand),//创建RoutedUICommand对象
            //    new InputGestureCollection() 
            //    { 
            //        //★⑤，修改此处三个参数，以便挂接快捷键。
            //        new KeyGesture(Key.S,ModifierKeys.Control,"Ctrl+S")
            //    });

            cmdBinding.Command = routedUICmd;
            cmdBinding.CanExecute += new CanExecuteRoutedEventHandler(cmdBinding_CanExecute);
            cmdBinding.Executed += new ExecutedRoutedEventHandler(cmdBinding_Executed);
        }

        #endregion

        #region 字段与属性===================================================================================================

        private static CommandBinding cmdBinding = new CommandBinding();
        /// <summary>
        /// 用在主窗口CommandBindings集合中的命令绑定。
        /// 
        /// 它的Command是RoutedUICommand。
        /// ——因此，RoutedUICommand是否可以运行将由CmdBinding的CanExecute事件决定。
        /// ——而且，RoutedUICommand的执行也是通过CmdBinding的Execute事件来进行的。
        /// </summary>
        public static CommandBinding CmdBinding
        {
            get { return cmdBinding; }
        }

        private static RoutedUICommand routedUICmd;
        /// <summary>
        /// [只读静态属性]表示在WPF系统中注册的一个RoutedUICommand。
        /// ——必须和CommandBinding配合才能使用。
        ///     CommandBinding要添加到主窗口的CommandBindings集合中；
        ///     RoutedUICommand则要向WPF系统注册。
        ///     
        /// ★说明：使用静态属性是因为这样在Xaml代码中比较便于绑定。
        /// </summary>
        public static RoutedUICommand RoutedUICmd
        {
            get { return routedUICmd; }
        }

        #endregion

        #region 方法=========================================================================================================

        static void cmdBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            //★⑧，修改此方法的实现。

            //考虑到性能问题，全部取消此判断。反正执行时会判断。
            //if (Globals.MainWindow == null)
            //{
            //    e.CanExecute = false;
            //    return;
            //}

            //EditorManager manager = Globals.MainWindow.EditorManager;
            //if (manager == null)
            //{
            //    e.CanExecute = false;
            //    return;
            //}

            //PageEditor mainPe = manager.GetMainSelectedPageEditor();
            //if (mainPe == null)
            //{
            //    e.CanExecute = false;
            //    return;
            //}

            e.CanExecute = true;
        }

        static void cmdBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            //★⑦，修改此方法的实现。

            LunarMessage.Warning(Execute());
        }

        /// <summary>
        /// [公开静态方法]即使此命令处于禁用状态，也可以通过代码调用此方法来执行特定任务！！！
        /// 
        /// 当被绑定的命令被调用（触发）时，会引发cmdBinding_Executed事件。
        /// 在cmdBinding_Executed事件处理器方法中已添加了调用Execute()方法的代码。
        /// 
        /// ——因此，触发命令，就相当于调用此方法！！！
        /// </summary>
        public static string Execute()
        {
            return CreateCopybook();
        }

        /// <summary>
        /// 创建字贴。由Ellipse部件组成每一个字。
        /// </summary>
        /// <param name="blankNextColumn">是否隔列空缺（以便临摹）。</param>
        /// <returns>正常执行返回strimg.Empty。</returns>
        public static string CreateCopybook()
        {
            if (Globals.MainWindow == null) return "　　Globals.MainWindow为null。";
            EditorManager manager = Globals.MainWindow.EditorManager;

            if (manager == null) return "　　未找到页面管理器。";

            PageEditor mainPe = manager.GetMainSelectedPageEditor();
            if (mainPe == null) return "　　未找到活动页面。";

            Rect adornedElementRect = Adorners.PageEditAreaGridAdorner.FormatRect(mainPe.EditArea);
            double startX, startY, endX, endY; int rowsCount, columnsCount;
            //每个Cell都是48*48，这样正好画正斜线和十字线。

            rowsCount = (int)(adornedElementRect.Height / 48);
            columnsCount = (int)(adornedElementRect.Width / 48);

            startX = (int)(adornedElementRect.Left + (adornedElementRect.Width - columnsCount * 48) / 2);
            startY = (int)(adornedElementRect.Top + (adornedElementRect.Height - rowsCount * 48) / 2);

            endX = startX + columnsCount * 48;
            endY = startY + rowsCount * 48;

            XmlNode widgetSetNode = mainPe.WidgetSetNode;
            if (widgetSetNode == null) return "　　未找到当前页面的WidgetSet节点。";

            string text;

            Dialogs.MuiltLineTextInputBox mtiBox = new Dialogs.MuiltLineTextInputBox(Globals.MainWindow,
                "　　请输入欲组成一页字贴的文本，超出的字符会被忽略。", Globals.AppName, string.Empty);
            if (mtiBox.ShowDialog() != true) return string.Empty;//用户取消操作。

            bool blankNextColumn = mtiBox.CkxBlankNextLine.IsChecked == true ? true : false;
            text = mtiBox.TbxInput.Text;

            if (string.IsNullOrEmpty(text)) return "　　未提供文本。";

            text = text.Replace("\r\n", "\n");

            ModifingInfo info = new ModifingInfo();
            info.ModifingDescription = "创建字贴页";
            ModifingItem<Action, ModifingInfo> mi = new ModifingItem<Action, ModifingInfo>(info);
            manager.GetSelectedPageEditorStatus(info);
            manager.GetSelectedWidgetStatus_Old(info);
            manager.GetSelectedWidgetStatus_New(info);

            int charCounts = rowsCount * columnsCount / 2;
            int i = 0;

            double xOffset = startX; double yOffset = startY;

            if (blankNextColumn)
            {
                for (int iy = 0; iy < rowsCount; iy += 2)
                {
                    if (i > text.Length) break;

                    xOffset = startX;
                    for (int ix = 0; ix < columnsCount; ix++)
                    {
                        if (i >= text.Length) break;

                        string x = text.Substring(i, 1);
                        i++;

                        if (x == "\n")
                        {
                            xOffset = startX;
                            break;//换行。
                        }

                        if (x != " " && x != "　")//全角空格、半角空格不添加部件。
                        {
                            XmlNode newNode = widgetSetNode.AppendXmlAsChild(
                                "<Widget Type=\"Ellipse\">" +
                                "<ParagraphSet>" +
                                "<Paragraph>" +
                                "<Text>" + x + "</Text>" +
                                "</Paragraph>" +
                                "</ParagraphSet>" +
                                "</Widget>");

                            Widgets.EllipseWidget newEllipse = new Widgets.EllipseWidget(mainPe);
                            newEllipse.XmlData = newNode;
                            newEllipse.NewID();
                            newEllipse.WidgetBackColor = Brushes.Transparent;

                            newEllipse.StartPoint = new Point(xOffset + 4, yOffset + 4);
                            newEllipse.EndPoint = new Point(xOffset + 44, yOffset + 44);

                            mainPe.AddWidget(newEllipse);

                            Action act = new Action(ActionType.WidgetAdded, mainPe.Id, newEllipse.Id, null, newNode.OuterXml);
                            mi.AddAction(act);

                            newEllipse.IsSelected = true;
                            info.AddWidgetID_NewSelected(newEllipse.Id);
                        }
                        xOffset += 48;
                    }
                    yOffset += 96;//隔行
                }
            }
            else
            {
                for (int iy = 0; iy < rowsCount; iy++)
                {
                    if (i > text.Length) break;

                    xOffset = startX;
                    for (int ix = 0; ix < columnsCount; ix++)
                    {
                        if (i >= text.Length) break;

                        string x = text.Substring(i, 1);
                        i++;

                        if (x == "\n")
                        {
                            xOffset = startX;
                            break;//换行。
                        }

                        if (x != " " && x != "　")//全角空格、半角空格不添加部件。
                        {
                            XmlNode newNode = widgetSetNode.AppendXmlAsChild(
                                "<Widget Type=\"Ellipse\">" +
                                "<ParagraphSet>" +
                                "<Paragraph>" +
                                "<Text>" + x + "</Text>" +
                                "</Paragraph>" +
                                "</ParagraphSet>" +
                                "</Widget>");

                            Widgets.EllipseWidget newEllipse = new Widgets.EllipseWidget(mainPe);
                            newEllipse.XmlData = newNode;
                            newEllipse.NewID();
                            newEllipse.WidgetBackColor = Brushes.Transparent;

                            newEllipse.StartPoint = new Point(xOffset + 4, yOffset + 4);
                            newEllipse.EndPoint = new Point(xOffset + 44, yOffset + 44);

                            mainPe.AddWidget(newEllipse);

                            Action act = new Action(ActionType.WidgetAdded, mainPe.Id, newEllipse.Id, null, newNode.OuterXml);
                            mi.AddAction(act);

                            newEllipse.IsSelected = true;
                            info.AddWidgetID_NewSelected(newEllipse.Id);
                        }
                        xOffset += 48;
                    }
                    yOffset += 48;
                }
            }

            manager.RegisterModifingItem(mi);

            return string.Empty;
        }

        #endregion
    }
}
